package com.hillky.emos.wx.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateRange;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.unit.DataUnit;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hillky.emos.wx.config.SystemConstants;
import com.hillky.emos.wx.domain.TbCheckin;
import com.hillky.emos.wx.domain.TbUser;
import com.hillky.emos.wx.exception.EmosException;
import com.hillky.emos.wx.mapper.TbHolidaysMapper;
import com.hillky.emos.wx.mapper.TbUserMapper;
import com.hillky.emos.wx.mapper.TbWorkdayMapper;
import com.hillky.emos.wx.service.TbCheckinService;
import com.hillky.emos.wx.mapper.TbCheckinMapper;
import com.hillky.emos.wx.utils.EmailUtils;
import org.jsoup.Jsoup;
import org.jsoup.helper.DataUtil;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Service;

import java.sql.Struct;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Set;

/**
* @author Hillky
* @description 针对表【tb_checkin(签到表)】的数据库操作Service实现
* @createDate 2023-01-29 10:56:24
*/
@Service
@Scope("prototype")
public class TbCheckinServiceImpl extends ServiceImpl<TbCheckinMapper, TbCheckin>
    implements TbCheckinService{


    @Autowired
    private TbWorkdayMapper workdayMapper;

    @Autowired
    private TbHolidaysMapper holidaysMapper;

    @Autowired
    private SystemConstants constants;

    @Autowired
    private TbCheckinMapper checkinMapper;

    @Autowired
    private TbUserMapper tbUserMapper;

    @Autowired
    private EmailUtils emailUtils;

    @Override
    public String validCanCheckIn(int userId, String date) {
        //查询当天是否是工作日
        boolean bool_1=workdayMapper.searchTodayIsWorkday()!=null ? true : false;
        boolean bool_2=holidaysMapper.searchTodayIsHoliday()!=null ? true : false;
        String type="工作日";
        if(DateUtil.date().isWeekend()){
            type="节假日";
        }
        if(bool_1){
            type="工作日";
        }else if(bool_2){
            type="节假日";
        }

        //根据类型去判断结果
        if(type.equals("节假日")){
            return "节假日不需要考勤";
        }else{
            //签到
            DateTime now = DateUtil.date();
            String start = DateUtil.today() + " " + constants.attendanceStartTime;
            String end = DateUtil.today() + " " + constants.attendanceEndTime;
            DateTime attendStart = DateUtil.parse(start);
            DateTime attendEnd = DateUtil.parse(end);
            if(now.isBefore(attendStart)){
                return "没到上班考勤开始时间";
            }else if(now.isAfter(attendEnd)){
                return "超过了上班考勤结束时间";
            }else{
                HashMap map = new HashMap();
                map.put("userId",userId);
                map.put("date",date);
                map.put("start",start);
                map.put("end",end);
                Integer res = checkinMapper.haveCheckin(map);
                boolean bool = res != null ? true : false;
                return bool?"今日已经考勤，不用重复考勤":"可以考勤";
            }
        }
    }

    @Override
    public void checkin(HashMap param) {
        //判断是否迟到
        DateTime d1 = DateUtil.date();
        DateTime d2 = DateUtil.parse(DateUtil.today() + " " + constants.attendanceStartTime);
        DateTime d3 = DateUtil.parse(DateUtil.today() + " " + constants.attendanceTime);
        DateTime d4 = DateUtil.parse(DateUtil.today() + " " + constants.attendanceEndTime);

        //签到状态
        int status=0;
        if(d1.isAfter(d2)&&d1.isBefore(d3)){
            //正常考勤
            status=1;
        }else if(d1.isAfter(d3)&&d1.isBefore(d4)){
            //考勤迟到
            status=2;
        }

        int userId = (int) param.get("userId");
        //TODO 人脸签到 思路就是先上传用户真实头像数据，然后使用百度智能云api的人脸比对，验证签到上传的与数据库中的图片两者对比的分数，分数高才能签到

        //使用jsoup解析网页内容  主要是查询疫情等级，现在没有了，但能学习到jsoup如何使用
        //查询疫情风险等级
//        int risk=1;
//        if(!StrUtil.isBlank(city)&&!StrUtil.isBlank(district)){
//            String code=cityDao.searchCode(city);
//            try{
//                String url = "http://m." + code + ".bendibao.com/news/yqdengji/?qu=" + district;
//                Document document= Jsoup.connect(url).get();
//                //获取css样式
//                Elements elements=document.getElementsByClass("list-content");
//                if(elements.size()>0){
//                    Element element=elements.get(0);
//                    String result=element.select("p:last-child").text();
////                            result="高风险";
//                    if("高风险".equals(result)){
//                        risk=3;
//                        //发送告警邮件
//                        HashMap<String,String> map=userDao.searchNameAndDept(userId);
//                        String name = map.get("name");
//                        String deptName = map.get("dept_name");
//                        deptName = deptName != null ? deptName : "";
//                        SimpleMailMessage message=new SimpleMailMessage();
//                        message.setTo(hrEmail);
//                        message.setSubject("员工" + name + "身处高风险疫情地区警告");
//                        message.setText(deptName + "员工" + name + "，" + DateUtil.format(new Date(), "yyyy年MM月dd日") + "处于" + address + "，属于新冠疫情高风险地区，请及时与该员工联系，核实情况！");
//                        emailTask.sendAsync(message);
//                    }
//                    else if("中风险".equals(result)){
//                        risk=2;
//                    }
//                }
//            }catch (Exception e){
//                log.error("执行异常",e);
//                throw new EmosException("获取风险等级失败");
//            }

        if(status!=0){
            //TODO 执行异步方法发送考勤邮件

            HashMap<String, String> hashMap = tbUserMapper.searchNameAndDept(userId);
            TbUser tbUser = tbUserMapper.selectById(userId);
            String email = tbUser.getEmail();
            String name = hashMap.get("name");
            String deptName = hashMap.get("dept_name");
            String text;
            if(status==1){
                text="正常";
            }else{
                text="迟到";
            }

            String context = "<b>尊敬的{}部门的{}：</b><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;您好，" +
                    "你已经考勤成功,考勤的状态：<b>{}</b>，" +
                    "<br><br><br><b>emos办公系统</b>";
            String html = StrUtil.format(context, deptName, name, text);
            ThreadUtil.execAsync(() -> {
                emailUtils.sendHtml("签到信息",html,email);
            });




            //可以签到，生成签到记录
            String city= (String) param.get("city");
            String district= (String) param.get("district");
            String address= (String) param.get("address");
            String country= (String) param.get("country");
            String province= (String) param.get("province");
            String photo = (String) param.get("photo");
            TbCheckin checkin = new TbCheckin();
            checkin.setAddress(address);
            checkin.setCity(city);
            checkin.setCountry(country);
            checkin.setDistrict(district);
            checkin.setDate(DateUtil.today());
            checkin.setCreateTime(d1);
            checkin.setProvince(province);
            checkin.setStatus(status);
            checkin.setPhoto(photo);
            checkin.setUserId(userId);
            this.save(checkin);
        }else{
            //不能签到的时间
            throw new EmosException("当前时间段不能进行签到");
        }

    }

    @Override
    public HashMap searchTodayCheckin(int userId) {
        return checkinMapper.searchTodayCheckin(userId);
    }

    @Override
    public Long searchCheckinDays(int userId) {
        return checkinMapper.searchCheckinDays(userId);
    }

    @Override
    public ArrayList<HashMap> searchWeekCheckIn(HashMap param) {
        ArrayList<HashMap> list = new ArrayList<>();
        //查询到签到记录
        ArrayList<HashMap> checkList = checkinMapper.searchWeekCheckin(param);
        //查询特殊节假日
        ArrayList<String> holidays = holidaysMapper.searchHolidaysInRange(param);
        //查询特殊工作日
        ArrayList<String> workdays = workdayMapper.searchWorkdaysInRange(param);
        //创建七天对象，进行封装放入list集中中
        DateTime startDate = DateUtil.parse(param.get("startDate").toString());
        DateTime endDate = DateUtil.parse(param.get("endDate").toString());
        DateRange range = DateUtil.range(startDate, endDate, DateField.DAY_OF_MONTH);
        range.forEach(one->{
            String date = one.toString("yyyy-MM-dd");
            String type="工作日";
            if(one.isWeekend()){
                type="节假日";
            }
            if(holidays!=null&&holidays.contains(date)){
                type="节假日";
            }else if(workdays!=null&&workdays.contains(date)){
                type="工作日";
            }

            String status="";
            if(type.equals("工作日")&&DateUtil.compare(one,DateUtil.date())<=0){
                status="缺勤";
                boolean flag=false;
                for (HashMap<String,String> map : checkList) {
                    if(map.containsValue(date)){
                        status=map.get("status");
                        flag=true;
                        break;
                    }
                }
                //当天签到考勤还没结束
                DateTime endTime=DateUtil.parse(DateUtil.today()+" "+constants.attendanceEndTime);
                String today=DateUtil.today();
                if(date.equals(today)&&DateUtil.date().isBefore(endTime)&&flag==false){
                    status="";
                }
            }
            HashMap map = new HashMap();
            map.put("date",date);
            map.put("type",type);
            map.put("status",status);
            map.put("day",one.dayOfWeekEnum().toChinese("周"));
            list.add(map);
        });
        return list;
    }
}




